3700 // Simple PIO-based (non-DMA) IDE driver code.
3701 
3702 #include "types.h"
3703 #include "defs.h"
3704 #include "param.h"
3705 #include "mmu.h"
3706 #include "proc.h"
3707 #include "x86.h"
3708 #include "traps.h"
3709 #include "spinlock.h"
3710 #include "buf.h"
3711 
3712 #define IDE_BSY       0x80
3713 #define IDE_DRDY      0x40
3714 #define IDE_DF        0x20
3715 #define IDE_ERR       0x01
3716 
3717 #define IDE_CMD_READ  0x20
3718 #define IDE_CMD_WRITE 0x30
3719 
3720 // idequeue points to the buf now being read/written to the disk.
3721 // idequeue->qnext points to the next buf to be processed.
3722 // You must hold idelock while manipulating queue.
3723 
3724 static struct spinlock idelock;
3725 static struct buf *idequeue;
3726 
3727 static int havedisk1;
3728 static void idestart(struct buf*);
3729 
3730 // Wait for IDE disk to become ready.
3731 static int
3732 idewait(int checkerr)
3733 {
3734   int r;
3735 
3736   while(((r = inb(0x1f7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
3737     ;
3738   if(checkerr && (r & (IDE_DF|IDE_ERR)) != 0)
3739     return -1;
3740   return 0;
3741 }
3742 
3743 
3744 
3745 
3746 
3747 
3748 
3749 
3750 void
3751 ideinit(void)
3752 {
3753   int i;
3754 
3755   initlock(&idelock, "ide");
3756   picenable(IRQ_IDE);
3757   ioapicenable(IRQ_IDE, ncpu - 1);
3758   idewait(0);
3759 
3760   // Check if disk 1 is present
3761   outb(0x1f6, 0xe0 | (1<<4));
3762   for(i=0; i<1000; i++){
3763     if(inb(0x1f7) != 0){
3764       havedisk1 = 1;
3765       break;
3766     }
3767   }
3768 
3769   // Switch back to disk 0.
3770   outb(0x1f6, 0xe0 | (0<<4));
3771 }
3772 
3773 // Start the request for b.  Caller must hold idelock.
3774 static void
3775 idestart(struct buf *b)
3776 {
3777   if(b == 0)
3778     panic("idestart");
3779 
3780   idewait(0);
3781   outb(0x3f6, 0);  // generate interrupt
3782   outb(0x1f2, 1);  // number of sectors
3783   outb(0x1f3, b->sector & 0xff);
3784   outb(0x1f4, (b->sector >> 8) & 0xff);
3785   outb(0x1f5, (b->sector >> 16) & 0xff);
3786   outb(0x1f6, 0xe0 | ((b->dev&1)<<4) | ((b->sector>>24)&0x0f));
3787   if(b->flags & B_DIRTY){
3788     outb(0x1f7, IDE_CMD_WRITE);
3789     outsl(0x1f0, b->data, 512/4);
3790   } else {
3791     outb(0x1f7, IDE_CMD_READ);
3792   }
3793 }
3794 
3795 
3796 
3797 
3798 
3799 
3800 // Interrupt handler.
3801 void
3802 ideintr(void)
3803 {
3804   struct buf *b;
3805 
3806   // Take first buffer off queue.
3807   acquire(&idelock);
3808   if((b = idequeue) == 0){
3809     release(&idelock);
3810     cprintf("Spurious IDE interrupt.\n");
3811     return;
3812   }
3813   idequeue = b->qnext;
3814 
3815   // Read data if needed.
3816   if(!(b->flags & B_DIRTY) && idewait(1) >= 0)
3817     insl(0x1f0, b->data, 512/4);
3818 
3819   // Wake process waiting for this buf.
3820   b->flags |= B_VALID;
3821   b->flags &= ~B_DIRTY;
3822   wakeup(b);
3823 
3824   // Start disk on next buf in queue.
3825   if(idequeue != 0)
3826     idestart(idequeue);
3827 
3828   release(&idelock);
3829 }
3830 
3831 // Sync buf with disk.
3832 // If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID.
3833 // Else if B_VALID is not set, read buf from disk, set B_VALID.
3834 void
3835 iderw(struct buf *b)
3836 {
3837   struct buf **pp;
3838 
3839   if(!(b->flags & B_BUSY))
3840     panic("iderw: buf not busy");
3841   if((b->flags & (B_VALID|B_DIRTY)) == B_VALID)
3842     panic("iderw: nothing to do");
3843   if(b->dev != 0 && !havedisk1)
3844     panic("idrw: ide disk 1 not present");
3845 
3846   acquire(&idelock);
3847 
3848 
3849 
3850   // Append b to idequeue.
3851   b->qnext = 0;
3852   for(pp=&idequeue; *pp; pp=&(*pp)->qnext)
3853     ;
3854   *pp = b;
3855 
3856   // Start disk if necessary.
3857   if(idequeue == b)
3858     idestart(b);
3859 
3860   // Wait for request to finish.
3861   // Assuming will not sleep too long: ignore proc->killed.
3862   while((b->flags & (B_VALID|B_DIRTY)) != B_VALID) {
3863     sleep(b, &idelock);
3864   }
3865 
3866   release(&idelock);
3867 }
3868 
3869 
3870 
3871 
3872 
3873 
3874 
3875 
3876 
3877 
3878 
3879 
3880 
3881 
3882 
3883 
3884 
3885 
3886 
3887 
3888 
3889 
3890 
3891 
3892 
3893 
3894 
3895 
3896 
3897 
3898 
3899 
